Node.js VM Module

V8 ভার্চুয়াল মেশিন পরিবেশে কোড কম্পাইল এবং চালানোর জন্য API শিখুন

ভিএম প্যাকেজের পরিচিতি

VM (ভার্চুয়াল মেশিন) মডিউল আপনাকে বিচ্ছিন্ন পরিবেশে কোড কম্পাইল এবং চালানোর অনুমতি দেয়।

এটি এর জন্য দরকারী:

নিরাপদে অবিশ্বস্ত কোড চলমান

একটি স্যান্ডবক্সে নিরাপদে অবিশ্বস্ত কোড চলছে৷

গতিশীলভাবে জাভাস্ক্রিপ্ট কোড মূল্যায়ন

গতিশীলভাবে জাভাস্ক্রিপ্ট কোড মূল্যায়ন

প্লাগইন এবং এক্সটেনশন সিস্টেম তৈরি করা

প্লাগইন এবং এক্সটেনশন সিস্টেম তৈরি করা

কাস্টম স্ক্রিপ্টিং পরিবেশ কনফিগার করা হচ্ছে

কাস্টম স্ক্রিপ্টিং পরিবেশ কনফিগার করা হচ্ছে

বিচ্ছিন্নভাবে পরীক্ষার কোড

বিচ্ছিন্নভাবে পরীক্ষার কোড

⚠️সতর্কতা:

যদিও VM মডিউল প্রধান জাভাস্ক্রিপ্ট পরিবেশ থেকে বিচ্ছিন্নতা প্রদান করে, এটি একটি সম্পূর্ণ নিরাপদ স্যান্ডবক্স নয়। অবিশ্বস্ত কোড চালানোর জন্য এটি একমাত্র নিরাপত্তা ব্যবস্থা হিসাবে ব্যবহার করা উচিত নয়।

একটি VM প্যাকেজ আমদানি করা হচ্ছে

VM প্যাকেজ ব্যবহার করার জন্য, আপনার Node.js অ্যাপ্লিকেশনে এটির প্রয়োজন হবে:

const vm = require('vm');

মূল ধারণা

ভিএম মডিউলটিতে বেশ কয়েকটি মূল উপাদান রয়েছে:

বল ব্যাখ্যা
Script কম্পাইল করা জাভাস্ক্রিপ্ট কোড যা বিভিন্ন পরিবেশে একাধিকবার চালানো যেতে পারে
Context একটি বিচ্ছিন্ন গ্লোবাল অবজেক্ট যেখানে স্ক্রিপ্ট চালানো হয় একটি স্যান্ডবক্সড পরিবেশের মতো
ContextifiedObject একটি VM পরিবেশের সাথে যুক্ত একটি অবজেক্ট এবং এটির গ্লোবাল অবজেক্ট হিসাবে কাজ করে

বেসিক অ্যাপ্লিকেশন: একটি পরিবেশে জাভাস্ক্রিপ্ট চালানো

একটি VM প্যাকেজ ব্যবহার করার সবচেয়ে সহজ উপায় হল একটি পরিবেশে কোড চালানো:

const vm = require('vm');

// Create a context object
const context = { x: 2 };

// Compile and run a script in the context
vm.createContext(context);
vm.runInContext('x = x * 2; y = 10;', context);

// Inspect the modified context
console.log(context); // Outputs: { x: 4, y: 10 }

এই উদাহরণে:

আমরা একটি পরিবর্তনশীল x দিয়ে একটি প্রসঙ্গ বস্তু তৈরি করি
vm.createContext() ""
আমরা এই পরিবেশে জাভাস্ক্রিপ্ট কোড চালাই যা x পরিবর্তন করে এবং y তৈরি করে
পরিবর্তনগুলি প্রসঙ্গে প্রতিফলিত হয়

ভিএম প্যাকেজ পদ্ধতি

স্ক্রিপ্ট পদ্ধতি

পদ্ধতি ব্যাখ্যা
vm.Script(code[, options]) একটি নতুন স্ক্রিপ্ট অবজেক্ট তৈরি করে যা কম্পাইল করা কোডকে উপস্থাপন করে
script.runInContext(contextObject[, options]) একটি নির্দিষ্ট পরিবেশে সংকলিত কোড চালায়
script.runInNewContext([contextObject][, options]) একটি নতুন পরিবেশে সংকলিত কোড চালায়
script.runInThisContext([options]) বর্তমান প্রেক্ষাপটে সংকলিত কোড চালায়

প্রসঙ্গ পদ্ধতি

পদ্ধতি ব্যাখ্যা
vm.createContext([contextObject][, options]) একটি নতুন পরিবেশ তৈরি করে যা স্ক্রিপ্ট চালানোর জন্য ব্যবহার করা যেতে পারে
vm.isContext(object) একটি বস্তু প্রাসঙ্গিক কিনা তা পরীক্ষা করে
vm.runInContext(code, contextObject[, options]) প্রদত্ত পরিবেশে কোড কম্পাইল করে এবং রান করে
vm.runInNewContext(code[, contextObject][, options]) একটি নতুন পরিবেশে কোড কম্পাইল করে এবং চালায়
vm.runInThisContext(code[, options]) বর্তমান প্রেক্ষাপটে কোডটি কম্পাইল এবং রান করে

স্ক্রিপ্ট তৈরি এবং কম্পাইল করা

ভাল পারফরম্যান্সের জন্য যখন আপনাকে একই কোড একাধিকবার চালানোর প্রয়োজন হয়, আপনি স্ক্রিপ্ট ক্লাস ব্যবহার করে এটি প্রি-কম্পাইল করতে পারেন:

const vm = require('vm');

// Compile the script once
const script = new vm.Script('x += 40; let z = 30;');

// Create multiple contexts
const context1 = { x: 10 };
const context2 = { x: 20 };

// Contextify the objects
vm.createContext(context1);
vm.createContext(context2);

// Run the same script in different contexts
script.runInContext(context1);
script.runInContext(context2);

console.log(context1); // Outputs: { x: 50, z: 30 }
console.log(context2); // Outputs: { x: 60, z: 30 }

দ্রষ্টব্য:

আলাদাভাবে স্ক্রিপ্ট কম্পাইল করা আরও কার্যকর যখন আপনাকে একই কোড একাধিকবার চালাতে হবে কারণ পার্সিং এবং কম্পাইলেশন ধাপগুলি শুধুমাত্র একবারই ঘটে।

কোড চালানোর বিভিন্ন উপায়

1. runInContext

পূর্বে তৈরি পরিবেশে কোড চালানো হচ্ছে:

const vm = require('vm');

const context = { value: 10 };
vm.createContext(context);

// Run directly
vm.runInContext('value += 5', context);
console.log(context.value); // 15

// Compile then run
const script = new vm.Script('value *= 2');
script.runInContext(context);
console.log(context.value); // 30

2. runInNewContext

একটি নতুন পরিবেশ তৈরি করে এবং এতে কোড চালায়:

const vm = require('vm');

// No need to call createContext first
const context = { value: 10 };
vm.runInNewContext('value += 5; result = value * 2;', context);

console.log(context); // { value: 15, result: 30 }

3. runInThisContext

বর্তমান V8 প্রসঙ্গে কোড চালানো হচ্ছে (যেমন eval কিন্তু নিরাপদ):

const vm = require('vm');

// Define a variable in the current scope
const locallet = 20;
let result;

// This won't have access to localVar
vm.runInThisContext('result = (typeof locallet !== "undefined" ? locallet : "not defined")');
console.log(result); // 'not defined'

// But it can access globals
global.globallet = 30;
vm.runInThisContext('result = globalVar');
console.log(result); // 30

// Compare with eval, which CAN access local variables
eval('result = localVar');
console.log(result); // 20

🔒দ্রষ্টব্য:

runInThisContext ইভালের অনুরূপ, কিন্তু যে সুযোগ থেকে এটি বলা হয় সেখানে স্থানীয় ভেরিয়েবলগুলিতে অ্যাক্সেস নেই। এটি এটিকে কিছুটা নিরাপদ করে তোলে কারণ এটি স্থানীয় ভেরিয়েবলগুলিকে প্রভাবিত করে কোড ইনজেকশন প্রবেশের ঝুঁকি হ্রাস করে।

টাইমআউট বিকল্পের সাথে কাজ করা

অন্তহীন লুপ বা দীর্ঘ-চলমান স্ক্রিপ্টগুলি প্রতিরোধ করতে স্ক্রিপ্ট সম্পাদনের জন্য একটি সময়সীমা সেট করা যেতে পারে:

const vm = require('vm');

const context = { result: 0 };
vm.createContext(context);

try {
  // This should timeout after 1000ms (1 second)
  vm.runInContext(`
    let counter = 0;
    while (true) {
      counter++;
      result = counter;
    }
  `, context, { timeout: 1000 });
} catch (err) {
  console.error(`Execution timed out: ${err.message}`);
  console.log(`Results before timeout: counter reached ${context.result}`);
}

সতর্কতা:

টাইমআউট বিকল্পটি গ্যারান্টি দেয় না যে নির্দিষ্ট সময়ে অপারেশনটি সঠিকভাবে শেষ হবে। প্রকৃত সময়সীমা সামান্য পরিবর্তিত হতে পারে।

Node.js কোর মডিউল অ্যাক্সেস নিয়ন্ত্রণ

ডিফল্টরূপে, Node.js কোর মডিউলের VM পরিবেশে চলমান কোডে অ্যাক্সেস নেই। আপনি কোন মডিউল উপলব্ধ তা নিয়ন্ত্রণ করতে পারেন:

const vm = require('vm');
const fs = require('fs');

// Create a sandbox with controlled access to core modules
const sandbox = {
  // Allow limited access to console
  console: {
    log: console.log,
    error: console.error
  },
  
  // Provide controlled access to fs module
  fs: {
    readFileSync: fs.readFileSync
  },
  
  // Custom utility
  util: {
    add: (a, b) => a + b,
    multiply: (a, b) => a * b
  },
  
  // No access to process, child_process, etc.
};

vm.createContext(sandbox);

// Run code with limited access
try {
  vm.runInContext(`
    // We can use the allowed methods
    console.log('Running in sandbox');
    console.log('2 + 3 =', util.add(2, 3));
    
    // Try to read a safe file
    try {
      const content = fs.readFileSync('example.txt', 'utf8');
      console.log('File content:', content);
    } catch (err) {
      console.error('File read error:', err.message);
    }
    
    // Try to access process (should fail)
    try {
      console.log('Process info:', process.version);
    } catch (err) {
      console.error('Cannot access process:', err.message);
    }
  `, sandbox);
} catch (err) {
  console.error('Sandbox execution failed:', err);
}

🛡️সতর্কতা:

যদিও আপনি নির্দিষ্ট মডিউলগুলিতে অ্যাক্সেস সীমাবদ্ধ করতে পারেন, এই পদ্ধতিটি সম্পূর্ণ নিরাপদ নয়। একজন দৃঢ়প্রতিজ্ঞ আক্রমণকারী এখনও স্যান্ডবক্স থেকে পালানোর উপায় খুঁজে পেতে পারে। সত্যিকারের নিরাপদ স্যান্ডবক্সিংয়ের জন্য, অতিরিক্ত বিচ্ছিন্নতা কৌশল বা বিশেষ লাইব্রেরি বিবেচনা করুন।

একটি সাধারণ টেমপ্লেট ইঞ্জিন তৈরি করা

ভিএম মডিউলটি একটি সাধারণ টেমপ্লেট মেশিন তৈরি করতে ব্যবহার করা যেতে পারে:

const vm = require('vm');

function renderTemplate(template, data) {
  // Create template function - replace {{ let }} with values
  const templateScript = `
    function template(data) {
      let output = \`${template.replace(/\{\{\s*(\w+)\s*\}\}/g, '${data.$1}')}\`;
      return output;
    }
    template(data);
  `;
  
  // Create a context with the data
  const context = { data };
  vm.createContext(context);
  
  // Execute the template function
  return vm.runInContext(templateScript, context);
}

// Example usage
const template = `












  {{ title }}


  

{{ title }}

Welcome, {{ name }}!

Today is {{ date }}

`; const data = { title: 'My Template Page', name: 'User', date: new Date().toLocaleDateString() }; const rendered = renderTemplate(template, data); console.log(rendered);

📝দ্রষ্টব্য:

এই উদাহরণটি একটি সাধারণ ব্যবহারের ক্ষেত্রে দেখায় যেখানে উৎপাদন টেমপ্লেট ইঞ্জিন যেমন হ্যান্ডেলবার বা EJS খুব শক্তিশালী এবং সুরক্ষিত। এই উদাহরণটি ইনজেকশন এন্ট্রি আক্রমণের জন্য ঝুঁকিপূর্ণ যদি ব্যবহারকারীর ডেটা সঠিকভাবে এস্কেপ করা হয়।

একটি প্লাগইনের বিন্যাস তৈরি করা

VM মডিউল প্লাগইন কনফিগারেশন তৈরি করার জন্য দরকারী যেখানে প্লাগইনগুলি লোড করা যায় এবং বিচ্ছিন্নভাবে চালানো যায়:

const vm = require('vm');
const fs = require('fs');
const path = require('path');

class PluginSystem {
  constructor() {
    this.plugins = new Map();
    this.api = {
      version: '1.0.0',
      registerHook: this.registerHook.bind(this),
      utils: {
        add: (a, b) => a + b,
        multiply: (a, b) => a * b,
        formatDate: (date) => new Date(date).toLocaleDateString()
      }
    };
    
    this.hooks = {
      init: [],
      process: [],
      shutdown: []
    };
  }
  
  // Register a plugin hook
  registerHook(hookName, callback) {
    if (this.hooks[hookName]) {
      this.hooks[hookName].push(callback);
      console.log(`Registered ${hookName} hook`);
    } else {
      console.error(`Invalid hook name: ${hookName}`);
    }
  }
  
  // Load a plugin from file
  loadPlugin(pluginName, pluginCode) {
    try {
      console.log(`Loading plugin: ${pluginName}`);
      
      // Create a sandbox for this plugin
      const sandbox = {
        console: {
          log: (msg) => console.log(`[${pluginName}] ${msg}`),
          error: (msg) => console.error(`[${pluginName}] ${msg}`)
        },
        setTimeout,
        clearTimeout,
        api: this.api
      };
      
      // Create context and run the plugin code
      const context = vm.createContext(sandbox);
      vm.runInContext(pluginCode, context);
      
      // Store the loaded plugin
      this.plugins.set(pluginName, {
        name: pluginName,
        sandbox
      });
      
      console.log(`Successfully loaded plugin: ${pluginName}`);
    } catch (err) {
      console.error(`Error loading plugin ${pluginName}:`, err.message);
    }
  }
  
  // Run all hooks of a specific type
  async runHooks(hookName, data) {
    console.log(`Running ${hookName} hooks...`);
    
    for (const hook of this.hooks[hookName]) {
      try {
        const result = await hook(data);
        console.log(`Hook result:`, result);
      } catch (err) {
        console.error(`Error in ${hookName} hook:`, err.message);
      }
    }
  }
  
  // Load all plugins from a directory
  loadPluginsFromDirectory(directory) {
    try {
      const files = fs.readdirSync(directory);
      
      for (const file of files) {
        if (file.endsWith('.js')) {
          const pluginName = path.basename(file, '.js');
          const pluginPath = path.join(directory, file);
          const pluginCode = fs.readFileSync(pluginPath, 'utf8');
          
          this.loadPlugin(pluginName, pluginCode);
        }
      }
    } catch (err) {
      console.error('Error loading plugins directory:', err.message);
    }
  }
  
  // Run the plugin system
  async run(data) {
    await this.runHooks('init', data);
    await this.runHooks('process', data);
    await this.runHooks('shutdown', data);
  }
}

// Example plugin code (normally this would be in a separate file)
const examplePlugin = `
// Register initialization hook
api.registerHook('init', async (data) => {
  console.log('Plugin initializing with data:', data);
  return 'Initialization complete';
});

// Register processing hook
api.registerHook('process', async (data) => {
  console.log('Processing data');
  return {
    processed: true,
    sum: api.utils.add(data.x, data.y),
    product: api.utils.multiply(data.x, data.y),
    date: api.utils.formatDate(new Date())
  };
});

// Register shutdown hook
api.registerHook('shutdown', async () => {
  console.log('Plugin shutting down');
  return 'Shutdown complete';
});

console.log('Plugin loaded with API version', api.version);
`;

// Create and run the plugin system
(async () => {
  const system = new PluginSystem();
  
  // Load plugins
  system.loadPlugin('example', examplePlugin);
  
  // You could also load from a directory
  // system.loadPluginsFromDirectory('./plugins');
  
  // Run the system
  await system.run({ x: 5, y: 10 });
})();

সেরা অনুশীলন এবং নিরাপত্তা ধারণা

নিরাপত্তা সেরা অনুশীলন

নিরাপত্তার জন্য শুধুমাত্র VM ক্লাস্টারিংয়ের উপর নির্ভর করবেন না:অবিশ্বস্ত কোডের জন্য অতিরিক্ত নিরাপত্তা ব্যবস্থা ব্যবহার করুন
নিয়ন্ত্রণ সংস্থান:নির্বাহিত কোডের জন্য সময়সীমা এবং মেমরি সীমা সেট করুন
নিয়ন্ত্রণ অ্যাক্সেস:স্যান্ডবক্সের জন্য শুধুমাত্র প্রয়োজনীয় কার্যকারিতা প্রদান করুন
এন্ট্রি পরীক্ষা করুন:VM এ প্রক্রিয়া করার আগে সমস্ত ইনপুট সাবধানে পরীক্ষা করুন
প্রক্রিয়া বিচ্ছিন্নতা বিবেচনা করুন:সর্বোচ্চ নিরাপত্তার জন্য, আলাদা প্রক্রিয়া বা পাত্রে অবিশ্বস্ত কোড চালান

কর্মক্ষমতা সেরা অনুশীলন

একবার স্ক্রিপ্ট কম্পাইল করুন:একাধিকবার চলে এমন কোডের জন্য নতুন vm.Script() ব্যবহার করুন
প্রসঙ্গ পুনরায় ব্যবহার করুন:নতুন পরিবেশ তৈরি করা ব্যয়বহুল, তাই যখনই সম্ভব পুনরায় ব্যবহার করুন
প্রসঙ্গ স্তর নিয়ন্ত্রণ করুন:কর্মক্ষমতা উন্নত করতে পরিবেশ ছোট রাখুন
বড় ডেটার সাথে সতর্ক থাকুন:পরিবেশের মধ্যে বড় ডেটা স্ট্রাকচার পাঠানো অদক্ষ হতে পারে

ভিএম প্যাকেজ বনাম ইভাল()

VM মডিউলটি eval() ব্যবহার করে বিভিন্ন সুবিধা প্রদান করে:

বৈশিষ্ট্য ভিএম প্যাকেজ eval()
স্থানীয় ভেরিয়েবল অ্যাক্সেস না (RunInThis Context সহ) হ্যাঁ
আলাদা করা আরও ভাল (ব্যক্তিগত প্রসঙ্গ) না (একই প্রসঙ্গ)
নিরাপত্তা ভাল (নিয়ন্ত্রিত পরিবেশ) খারাপ (সব অ্যাক্সেসযোগ্য)
পুনরাবৃত্তি অপারেশন জন্য কর্মক্ষমতা সেরা (প্রি-প্যাকেজ করা যেতে পারে) খারাপ (প্রতিবার কম্পাইল করে)
চলাচলের উপর নিয়ন্ত্রণ এছাড়াও (টাইমআউট, ইত্যাদি) কম

VM প্যাকেজের সীমাবদ্ধতা

একটি সম্পূর্ণ স্যান্ডবক্স নয়:ভিএম পরিবেশগুলি পৃথক প্রক্রিয়াগুলির মতো সত্য বিচ্ছিন্নতা প্রদান করে না
কোন CPU বা মেমরির সীমাবদ্ধতা নেই:সম্পদের ব্যবহার সরাসরি নিয়ন্ত্রণ করতে পারে না (শুধুমাত্র টাইমআউট উপলব্ধ)
প্রোটোটাইপ দূষণ বিপদ:VM পরিবেশে কোড এখনও জাভাস্ক্রিপ্ট প্রোটোটাইপ পরিবর্তন করতে পারে
সিঙ্ক্রোনাস গতি:চলমান কোড ইভেন্ট লুপকে ব্লক করে (যদি না আপনি এটি একটি কর্মী থ্রেডে চালান)।
ডিবাগিং চ্যালেঞ্জ:VM পরিবেশে চলমান কোড ডিবাগ করা কঠিন হতে পারে

🚨সতর্কতা:

নিরাপত্তা-সমালোচনামূলক অ্যাপ্লিকেশনগুলির জন্য, আরও শক্তিশালী স্যান্ডবক্সিং সমাধান বিবেচনা করুন যেমন চাইল্ড_প্রসেস প্যাকেজ, পাত্রে বা বিশেষায়িত লাইব্রেরি যেমন vm2 সহ পৃথক প্রক্রিয়া।

সারাংশ

Node.js VM V8 JavaScript . :

কিছু ডিগ্রী বিচ্ছিন্নতার সাথে গতিশীলভাবে কোড চালানো
নিরাপদ এক্সটেনসিবল প্লাগইন সিস্টেম তৈরি করা
টেমপ্লেট ইঞ্জিন এবং স্ক্রিপ্টিং পরিবেশ কনফিগার করা হচ্ছে
নিয়ন্ত্রিত পরিবেশে পরীক্ষার কোড

অবিশ্বস্ত কোড চালানোর জন্য সম্পূর্ণ নিরাপত্তা সমাধান না হলেও, VM মডিউলটি eval() এর চেয়ে বেশি বিচ্ছিন্নতা প্রদান করে এবং Node.js অ্যাপ্লিকেশনের মধ্যে জাভাস্ক্রিপ্ট মূল্যায়নের জন্য এটি একটি মূল্যবান টুল।

উন্নত পরিবেশ ব্যবস্থাপনা

কাস্টম গ্লোবাল এবং মডিউলগুলির সাথে কীভাবে জটিল VM পরিবেশ তৈরি এবং পরিচালনা করবেন তা শিখুন:

1. গ্লোবাল ভেরিয়েবল সহ একটি কাস্টম পরিবেশ তৈরি করা

const vm = require('vm');
const util = require('util');

// Create a custom context with specific global variables
const context = {
  console: {
    log: (...args) => {
      // Custom console.log implementation
      process.stdout.write('Custom Log: ' + util.format(...args) + '\n');
    },
    error: console.error,
    warn: console.warn,
    info: console.info
  },
  // Add custom utilities
  utils: {
    formatDate: () => new Date().toISOString(),
    generateId: () => Math.random().toString(36).substr(2, 9)
  },
  // Add a safe require function
  require: (moduleName) => {
    const allowedModules = ['path', 'url', 'util'];
    if (!allowedModules.includes(moduleName)) {
      throw new Error(`Module '${moduleName}' is not allowed`);
    }
    return require(moduleName);
  }
};

// Contextify the object
vm.createContext(context);

// Run code in the custom context
const code = `
  console.log('Current time:', utils.formatDate());
  console.log('Generated ID:', utils.generateId());
  
  try {
    const fs = require('fs'); // This will throw an error
  } catch (err) {
    console.error('Security error:', err.message);
  }
  
  // This will work as it's an allowed module
  const path = require('path');
  console.log('Current directory:', path.dirname('/path/to/file.txt'));
`;

try {
  vm.runInContext(code, context, { filename: 'custom-context.js' });
} catch (err) {
  console.error('Script execution failed:', err);
}

নিরাপত্তা সেরা অনুশীলন

একটি VM ক্লাস্টার ব্যবহার করার সময়, নিরাপত্তা আপনার প্রথম অগ্রাধিকার হওয়া উচিত। এখানে কিছু সেরা অনুশীলন রয়েছে:

const vm = require('vm');
const { execSync } = require('child_process');

// UNSAFE: Directly executing untrusted code
function unsafeEval(code) {
  // This is dangerous as it has access to the entire Node.js environment
  return vm.runInThisContext(code);
}

// SAFER: Isolated context with limited access
function safeEval(code, timeout = 1000) {
  // Create a context with only the necessary globals
  const context = {
    console: {
      log: console.log,
      error: console.error
    },
    // Add safe utilities
    Math: Object.create(null),
    JSON: {
      parse: JSON.parse,
      stringify: JSON.stringify
    },
    // Add a safe setTimeout with limits
    setTimeout: (fn, delay) => {
      if (delay > 1000) delay = 1000; // Cap delay at 1 second
      return setTimeout(fn, delay);
    }
  };
  
  // Copy safe methods from Math
  Object.getOwnPropertyNames(Math)
    .filter(prop => typeof Math[prop] === 'function')
    .forEach(prop => {
      context.Math[prop] = Math[prop];
    });
  
  // Create the context without prototype access
  const sandbox = vm.createContext(context, {
    name: 'sandbox',
    codeGeneration: {
      strings: false,
      wasm: false
    }
  });
  
  // Run the code with a timeout
  try {
    const script = new vm.Script(`
      (function() {
        "use strict";
        ${code}
      })();
    `, {
      filename: 'sandbox.js',
      lineOffset: 0,
      displayErrors: true,
      timeout: timeout,
      microtaskMode: 'afterEvaluate'
    });
    
    return script.runInContext(sandbox, { timeout });
  } catch (err) {
    console.error('Script execution failed:', err.message);
    throw new Error('Script execution failed');
  }
}

// Example of safe evaluation
try {
  const result = safeEval(`
    function add(a, b) { return a + b; }
    add(2, 3);
  `);
  console.log('Safe evaluation result:', result); // Outputs: 5
  
  // This will be caught by our safe evaluator
  safeEval('process.exit(1)');
} catch (err) {
  console.error('Caught error:', err.message);
}

// Example of security risks
console.log('\nTesting security risks:');

try {
  console.log('1. Accessing process:');
  safeEval('process.versions.node');
} catch (err) {
  console.log('✓ Blocked access to process object');
}

try {
  console.log('2. Infinite loop:');
  safeEval('while(true){}');
} catch (err) {
  console.log('✓ Caught infinite loop with timeout');
}

try {
  console.log('3. Prototype pollution:');
  safeEval('({}).constructor.prototype.polluted = true');
  console.log('✓ Blocked prototype pollution');
} catch (err) {
  console.log('✓ Blocked prototype pollution');
}

🔒গুরুত্বপূর্ণ:

একটি VM ব্লক একটি নিরাপত্তা সীমানা নয়। অবিশ্বস্ত কোড চালানোর জন্য ডকার, AWS Lambda, বা Google ক্লাউড ফাংশনগুলির মতো ডেডিকেটেড স্যান্ডবক্সিং সমাধানগুলি ব্যবহার করার কথা বিবেচনা করুন৷

কর্মক্ষমতা অপ্টিমাইজেশান

এই কৌশলগুলির সাথে ভিএম কর্মক্ষমতা অপ্টিমাইজ করুন:

const vm = require('vm');
const { performance, PerformanceObserver } = require('perf_hooks');

// 1. Compile once, run many times
const expensiveCalculation = new vm.Script(`
  function calculate(n) {
    let result = 0;
    for (let i = 0; i < n; i++) {
      result += Math.sqrt(i) * Math.PI;
    }
    return result;
  }
  
  // Return the function reference
  calculate;
`);

// Create a context
const context = { Math };
vm.createContext(context);

// Run once to get the function
const calculate = expensiveCalculation.runInContext(context);

// Now we can call the function multiple times without recompiling
console.log('Result (n=1000):', calculate(1000));
console.log('Result (n=2000):', calculate(2000));

// 2. Use code caching for better performance
const cache = new Map();

function compileWithCache(code, filename) {
  if (cache.has(code)) {
    console.log(`Using cached script for ${filename}`);
    return cache.get(code);
  }
  
  console.log(`Compiling script for ${filename}`);
  const script = new vm.Script(code, {
    filename,
    cachedData: null, // Will be populated on first run
    produceCachedData: true
  });
  
  cache.set(code, script);
  return script;
}

// 3. Measure performance
function measurePerformance() {
  const obs = new PerformanceObserver((items) => {
    const entry = items.getEntries()[0];
    console.log(`\nExecution time for ${entry.name}: ${entry.duration.toFixed(2)}ms`);
    performance.clearMarks();
  });
  obs.observe({ entryTypes: ['measure'] });
  
  // Test with different script sizes
  const smallScript = new vm.Script('let sum = 0; for (let i = 0; i < 1000; i++) sum += i; return sum;');
  const largeScript = new vm.Script(`
    function processData(data) {
      return data.map(x => ({
        ...x,
        processed: true,
        timestamp: Date.now(),
        hash: require('crypto').createHash('md5').update(JSON.stringify(x)).digest('hex')
      }));
    }
    
    // Process sample data
    const data = Array(1000).fill(null).map((_, i) => ({ id: i, value: Math.random() }));
    return processData(data);
  `);
  
  // Measure execution
  performance.mark('small-start');
  smallScript.runInThisContext();
  performance.mark('small-end');
  
  performance.mark('large-start');
  largeScript.runInThisContext();
  performance.mark('large-end');
  
  performance.measure('Small script execution', 'small-start', 'small-end');
  performance.measure('Large script execution', 'large-start', 'large-end');
}

// Run performance test
measurePerformance();

// 4. Reuse contexts for better performance
function createOptimizedContext() {
  const context = {
    // Only include what's necessary
    console: {
      log: console.log,
      error: console.error
    },
    // Add required globals
    setTimeout,
    clearTimeout,
    // Add custom utilities
    utils: {
      formatNumber: n => new Intl.NumberFormat().format(n),
      formatDate: d => d.toISOString()
    }
  };
  
  // Create context once
  vm.createContext(context);
  return context;
}

// Reuse the same context for multiple scripts
const sharedContext = createOptimizedContext();

// Run multiple scripts with the same context
function runWithSharedContext(code) {
  try {
    const script = new vm.Script(code);
    return script.runInContext(sharedContext);
  } catch (err) {
    console.error('Script execution failed:', err);
    throw err;
  }
}

// Example usage
const script1 = 'console.log("Script 1:", utils.formatNumber(1234567.89));';
const script2 = 'console.log("Script 2:", utils.formatDate(new Date()));';

runWithSharedContext(script1);
runWithSharedContext(script2);

কর্মক্ষমতা টিপস:

রি-কম্পাইলেশন ওভারহেড এড়াতে যদি সম্ভব হয় স্ক্রিপ্টগুলি প্রি-কম্পাইল করুন
প্রতিটি রানের জন্য নতুন তৈরি করার পরিবর্তে প্রসঙ্গগুলি পুনরায় ব্যবহার করুন
শুধুমাত্র প্রয়োজনীয় গ্লোবাল যোগ করে পরিবেশের আকার হ্রাস করুন
ঘন ঘন চালানো স্ক্রিপ্টের জন্য কোড ক্যাশিং ব্যবহার করুন
প্রতিবন্ধকতা সনাক্ত করতে কর্মক্ষমতা নিরীক্ষণ
CPU-নিবিড় অপারেশনের জন্য কর্মী থ্রেড বিবেচনা করুন

অনুশীলন করুন

সঠিক প্যাকেজ নাম নির্বাচন করুন.

The ______ module provides APIs for compiling and running code within V8 Virtual Machine contexts.

v8
✗ ভুল! "v8" মডিউল V8 ইঞ্জিনের জন্য নিম্ন-স্তরের API প্রদান করে
vm2
✗ ভুল! "vm2" একটি তৃতীয় পক্ষের প্যাকেজ, Node.js-এর অন্তর্নির্মিত প্যাকেজ নয়
vm
✓ ঠিক আছে! "vm" মডিউল V8 ভার্চুয়াল মেশিন পরিবেশের মধ্যে কোড কম্পাইল এবং চালানোর জন্য API প্রদান করে
context
✗ ভুল! "প্রসঙ্গ" Node.js-এ একটি বৈধ সেট নয়